package com.jgy.rabbit;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jgy.entity.FOrder;
import com.jgy.mapper.FOrderMapper;
import com.jgy.utils.DateUtil;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.List;

/**
 * 死信队列超时时间设置实现订单超时案例
 * @author wwuwentao
 */
@Slf4j
@Component
public class DeadLetterConsumerAnnotatedEdition {
    @Resource
    private FOrderMapper fOrderMapper;

    /**
     * 该队列的消息为死信始终消费不会成功等到到了超时时间则会将消息投递到x-dead-letter-exchange交换机中由绑定的队列来进行处理
     */
    @RabbitListener(bindings = {
            @QueueBinding(value = @Queue(value = DeadLetterQueueConfig.DEAD_LETTER_QUEUE, arguments =
                    {@Argument(name = "x-dead-letter-exchange", value = DeadLetterQueueConfig.ORDER_TIMEOUT_EXCHANGE),
                            @Argument(name = "x-dead-letter-routing-key", value = DeadLetterQueueConfig.ORDER_TIMEOUT_ROUTING_KEY),
                            @Argument(name = "x-message-ttl", value = DeadLetterQueueConfig.X_MESSAGE_TTL, type = "java.lang.Long")
                            // ,@Argument(name = "x-max-length",value = "5",type = "java.lang.Integer")队列最大长度
                    }),//可以指定多种属性
                    exchange = @Exchange(value = DeadLetterQueueConfig.DEAD_LETTER_EXCHANGE),
                    key = {DeadLetterQueueConfig.DEAD_LETTER_ROUTING_KEY}
            )
    })
    @RabbitHandler
    public void deadLetterConsumer(Message message, Channel channel) throws Exception {
        /*
         * deliveryTag：该消息的index
         * multiple: ture确认本条消息以及之前没有确认的消息(批量)，false仅确认本条消息
         * requeue: true该条消息重新返回MQ queue，MQ broker将会重新发送该条消息
         */
        channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
    }

    /**
     * 处理死信队列超时的订单
     */
    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = DeadLetterQueueConfig.ORDER_TIMEOUT_EXCHANGE, durable = "true", type = "direct"),
            value = @Queue(value = DeadLetterQueueConfig.ORDER_TIMEOUT_QUEUE, durable = "true"),
            key = DeadLetterQueueConfig.ORDER_TIMEOUT_ROUTING_KEY
    ))
    public void canleOrder(String context, Message message, Channel channel) throws IOException {
        log.info("当前时间:{} 订单取消订单号:{}", DateUtil.getCuurentDateStr(),context);
        //首先查询订单状态
        QueryWrapper<FOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(FOrder::getOrderNo,context);
        List<FOrder> fOrders = fOrderMapper.selectList(queryWrapper);
        fOrders.forEach(order -> {
            Integer payState = order.getPayState();
            //未支付
            if (payState == 0){
                int res = fOrderMapper.deleteById(order.getId());
                log.info("超时订单删除情况:{}",res);
            }else {
                log.info("订单已付款无需删除订单:{}",payState);
            }

        });
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);//仅确认本条消息
    }

}
